package com.loser.gateway.mq.consumer;

import com.loser.gateway.mysql.entity.CmdConfig;
import com.loser.gateway.mysql.service.CmdConfigService;
import com.loser.module.base.mq.gateway.CmdRegisterDTO;
import com.loser.module.base.mq.gateway.GateWayConst;
import com.loser.redis.core.RedisHandler;
import com.loser.utils.DateUtils;
import com.loser.utils.ParamsUtil;
import com.loser.utils.trace.MDCUtil;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Component
public class CmdRegisterConsumer {

    @Autowired
    private RedisHandler redisHandler;
    @Autowired
    private CmdConfigService cmdConfigService;

    @RabbitListener(
            // 绑定队列
            bindings = {
                    // 绑定队列的类
                    @QueueBinding(
                            // 1.队列名称
                            value = @Queue(GateWayConst.CmdRegister.Queue.gateWay),
                            // 消息交换器 1.交换器名称，2.交换器类型
                            exchange = @Exchange(value = GateWayConst.CmdRegister.exchange, type = ExchangeTypes.FANOUT))
            }, concurrency = "1")
    public void receiver(@Payload CmdRegisterDTO msg, @Headers Map<String, Object> headers, Channel channel) throws IOException {

        long deliveryTag = (long) headers.get(AmqpHeaders.DELIVERY_TAG);

        try {
            MDCUtil.setTraceId(msg.getTraceId());
            log.info("CmdRegisterConsumer data {}", msg);
            String lock = "CMD:REGISTER:%S";
            String lockKey = String.format(lock, msg.getCmd());
            if (!redisHandler.lock(lockKey, lockKey, DateUtils.SECONDS_PER_MINUTE)) {
                return;
            }
            CmdConfig dbData = cmdConfigService.getById(msg.getCmd());
            if (Objects.nonNull(dbData)) {
                return;
            }
            CmdConfig data = ParamsUtil.copyProperties(msg, CmdConfig.class);
            cmdConfigService.save(data);
        } catch (Exception e) {
            log.error("CmdRegisterConsumer throw an error data {}", msg, e);
        } finally {
            // mq消息ack
            channel.basicAck(deliveryTag, false);
            MDCUtil.removeTraceId();
        }

    }

}
